#pragma once
#include <iostream>
#include <functional>

#include "Socket.hpp"

namespace TcpServerArea
{
    using namespace SocketArea;

    using tcphandler_t = std::function<bool(sock_ptr,InetAddr)>;

    class TcpServer
    {
    public:
        TcpServer(int port):
        _listensockfd(std::make_shared<TcpSocket>())
        ,_is_running(false)
        ,_port(port)
        {
        }

        void InitTcpServer(tcphandler_t tcp_t)
        {
            _tcp_t = tcp_t;
            _listensockfd->BulidListenSockfd(_port);
        }
        void Start()
        {
            _is_running = true;
            while(_is_running)
            {
                InetAddr client;
                //存储客户端信息
                //返回的新的套接字使用 sockptr 接收
                auto sockptr = _listensockfd->Accepter(&client);
                if(!sockptr) continue;
                LOG(LogLevel::DEBUG)<<"get a new client: "<<client.NetAddr();

                pid_t id = fork();
                if(id==0)
                {
                    _listensockfd->Close();
                    if(fork()>0) exit(0);

                    //执行业务
                    _tcp_t(sockptr,client);
                    exit(0);
                }

                sockptr->Close();
                waitpid(id,nullptr,0);
                sleep(1);
            }
            _is_running = false;
        }
        ~TcpServer()
        {
            _listensockfd->Close();
        }

    private:
        std::shared_ptr<Socket> _listensockfd;
        bool _is_running;
        int _port;

        tcphandler_t _tcp_t;
    };
}